package com.zxp.web.jwt;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.Date;
import java.util.Map;

/**
 * @author MasterZ
 * @Date 2025/10/6 10:55
 */
@Data
@Component
@ConfigurationProperties(prefix = "jwt")
public class JwtUtils {
    private String issuer;
    private String secret;
    private Integer expiration;

    //生成token，map:自定义参数
    public String generateToken(Map<String, String> map) {
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.MINUTE, expiration);
        JWTCreator.Builder builder = JWT.create();
        map.forEach(builder::withClaim);
        return builder.withIssuer(issuer).withIssuedAt(new Date()).withExpiresAt(instance.getTime()).sign(Algorithm.HMAC256(secret));
    }

    //验证令牌是否合法
    public boolean verify(String token) {
        try {
            JWT.require(Algorithm.HMAC256(secret)).build().verify(token);
        } catch (JWTVerificationException e) {
            return false;
        }
        return true;
    }

    //解析token
    public DecodedJWT jwtDecode(String token) {
        try {
            return JWT.require(Algorithm.HMAC256(secret)).build().verify(token);
        } catch (SignatureVerificationException e) {
            throw new RuntimeException("token签名错误");
        } catch (AlgorithmMismatchException e) {
            throw new RuntimeException("token算法不匹配");
        } catch (TokenExpiredException e) {
            throw new RuntimeException("token过期");
        } catch (Exception e) {
            throw new RuntimeException("token解析失败");
        }
    }
}
